//go:build ignore
// +build ignore

package main

import "fmt"

const (
	MAX_WORKERS  = 10
	RANGE        = 100
	CHANNAL_SIZE = 10
)

// 任务结构体
// 完成对st到ed的累加，存入result管道
type task struct {
	st, ed int
	result chan<- int
}

// 任务的工作方法
func (t *task) do() {
	sum := 0
	for i := t.st; i <= t.ed; i++ {
		sum += i
	}
	t.result <- sum
}

func initTask(tasks chan task, result chan int, rg int) {
	// 以10个为一组，构建每个task
	st, ed, p := 1, 10, 0
	for rg >= 10 {
		t := task{st + 10*p, ed + 10*p, result}
		p++
		rg -= 10
		tasks <- t
	}
	if rg != 0 {
		t := task{st + 10*p, rg + 10*p, result}
		tasks <- t
	}
	// 任务布置完毕，关闭管道输入
	close(tasks)
}

// 每个worker的工作函数
func doTask(tasks chan task, done chan bool) {
	for t := range tasks {
		t.do()
	}
	// 上面的循环结束代表已经遍历完tasks，添加一个完成状态到done管道
	done <- true
}

// 调度workers容量的工作池的函数
func processTask(tasks chan task, done chan bool, result chan int, workers int) {
	// 启动workers个协程
	for i := 0; i < workers; i++ {
		go doTask(tasks, done)
	}
	for i := 0; i < workers; i++ {
		// 收集到全部workers个完成状态即完成了工作
		<-done
	}
	// 关闭完成标志管道
	close(done)
	// 需要关闭result管道，不然下面getTaskResult会造成死锁
	close(result)
}

func getTaskResult(result chan int, sum *int) {
	for r := range result {
		*sum += r
	}
}

func main() {
	sum, size, rg, mw := 0, CHANNAL_SIZE, RANGE, MAX_WORKERS
	tasks := make(chan task, size)
	done := make(chan bool)
	result := make(chan int)
	// 布置任务
	go initTask(tasks, result, rg)
	// 执行任务
	go processTask(tasks, done, result, mw)
	// 取得结果
	getTaskResult(result, &sum)
	fmt.Println(sum)
}
